/*
 * David Li 2010. For Quotespeed.
 */
if (!Util) {
    var Util = {};
}

/*Scrollbar*/
Util.Scrollbar = function(panelObj, target, oConfig, callback){
    this.panelObj = panelObj;
    this.container = panelObj.el;
    this.target = target;
    this.html = '<a class="rtq-scrollbar-up">UP</a><div class="rtq-scrollbar-bar"></div><a class="rtq-scrollbar-down">DOWN</a>';
    this.mod;
    this.bar;
    this.btnUp;
    this.btnDown;
    this.scrollTimer = null;
    this.scrolling = false;
    this.dragPos = {x:0,y:0};
    this.len = 0;
    this.scrollLength = 0;
    this.isShow = false;
    this.parentPadding = 0;
    this.barBorder = 2;
    this.barLen = 0;
    this.cfg = {
        disable:false,
        type:'y',
        modBorder:2,
        aW:12 //arrow Width
    };
    if(oConfig) {
        $.extend(this.cfg, oConfig);
    }
    this.CB = {
        onScroll:function(s){},
        onScrollEnd:function(s){}
    };
    if(callback) {
        $.extend(this.CB, callback);
    }
    this.init();
};
Util.Scrollbar.prototype = {
    init: function(){
        var self = this;
        
        this.mod = $('<div class="rtq-scrollbar">').html(this.html).addClass((this.cfg.type == 'y') ? 'rtq-scrollbar-y' : 'rtq-scrollbar-x').bind('click', {
            self: this
        }, this._clickScroll);
        
        this.bar = this.mod.find('.rtq-scrollbar-bar').bind('mousedown', {
            self: this
        }, this._startDrag).bind('mouseup', {
            self: this
        }, this._stopDrag);
        this.btnUp = this.mod.find('.rtq-scrollbar-up').bind('mousedown', {
            self: this
        }, this._startScrollUp).bind('mouseup', {
            self: this
        }, this._stopScroll);
        this.btnDown = this.mod.find('.rtq-scrollbar-down').bind('mousedown', {
            self: this
        }, this._startScrollDown).bind('mouseup', {
            self: this
        }, this._stopScroll);
        
        //this.parentPadding = ((this.cfg.type=='y')?this.container.css('paddingRight'):this.container.css('paddingBottom')).replace('px', '');
        this.parentPadding = this.cfg.aW;
        //this.reSize();
        //this._setParentPadding(this.parentPadding);
        this.mod.appendTo(this.container);
        
        this.scrollTo(0);
    },
    reSize:function(show){
        this._resetBar();
        this.scrollTo(this._getScrollTop());
        /*
        if(this.len < this.scrollLength && !this.isShow){ //show
            this.show();
            this._setParentPadding(this.parentPadding);
        }else if(this.len >= this.scrollLength){ //hide
            this.hide();
            this._setParentPadding(0);
        }
        */
        if(show){
            if (!this.isShow) {
                this.show();
                this._setParentPadding(this.parentPadding);
            }
        }else{ //hide
            if (this.isShow) {
                this.hide();
                this._setParentPadding(0);
            }
        }
    },
    scrollTo:function(i){
        var maxScrollTop = this.scrollLength - this.len;
        i = i<0?0:(i>maxScrollTop?maxScrollTop:i);
        
        if (i <= maxScrollTop && i>=0) {
            this._scrollTo(i);
        }
    },
	scrollPercentTo:function(p){
		this.scrollTo(p*(this.scrollLength - this.len));
	},
    show:function(){
        this.mod.show();
        this.isShow = true;
    },
    hide:function(){
        this.mod.hide();
        this.isShow = false;
    },
    _resetBar:function(){
        if (this.cfg.type == 'y') {
            var h = this.target.height();
            if (h && h >= this.cfg.aW * 2) {
                this.len = h - this.cfg.modBorder; //this.target.height();
                this.scrollLength = this.target[0].scrollHeight || 1;
                this.mod.css({
                    height: this.len
                });
                
                this.barLen = Math.round((this.len - this.cfg.aW * 2 ) * this.len / this.scrollLength);
                this.bar.css({
                    height: Math.max(this.barLen - this.barBorder, 2)
                });
            }
        }
        else {
            var w = this.target.width();
            if (w && w >= this.cfg.aW * 2) {
                this.len = w - this.cfg.modBorder;//this.target.width();
                this.scrollLength = this.target[0].scrollWidth || 1;
                this.mod.css({
                    width: this.len
                });
                this.barLen = Math.round((this.len - this.cfg.aW * 2 ) * this.len / this.scrollLength);
                this.bar.css({
                    width: Math.max(this.barLen - this.barBorder, 2)
                });
            }
        }
    },
    _setParentPadding:function(padding){
        if (this.cfg.type == 'y') {
            //this.container.css({paddingRight:padding});
            this.target.css({width:this.container.width()-padding});
        }
        else {
            this.target.css({height:this.container.height()-padding});
            //this.container.css({paddingBottom:padding});
        }
    },
    _scrollTo:function(i){
        this.CB.onScroll(i); //event
        var position = Math.round((i * (this.len-this.cfg.aW*2-this.barLen) / (this.scrollLength - this.len)) + this.cfg.aW );
        //position = position>this.cfg.aW?((position+this.barLen)>(this.len-this.cfg.aW)?):this.cfg.aW;
        if(position<this.cfg.aW){
            position = this.cfg.aW;
        }else if((position+this.barLen+this.barBorder)>(this.len-this.cfg.aW)){
            position = this.len - this.cfg.aW - this.barLen + this.cfg.modBorder;
        }
        if (this.cfg.type == 'y') {
            this.target.scrollTop(i);
            this.bar.css({
                top: position || 0
            });
        }else{
            this.target.scrollLeft(i);
            this.bar.css({
                left: position || 0
            });
        }
    },
    _getScrollTop:function(){
        return (this.cfg.type == 'y')?this.target.scrollTop():this.target.scrollLeft();
    },
    _clickScroll:function(e){
        if ($(e.target).hasClass('rtq-scrollbar')) {
            var self = e.data.self;
            self.scrolling = true;
            var offset = (self.cfg.type == 'y')?e.clientY - self.bar.offset().top:e.clientX - self.bar.offset().left;
            if (offset > 0) {
                self.scrollTo(self._getScrollTop() + 100);
            }
            else {
                self.scrollTo(self._getScrollTop() - 100);
            }
            self.CB.onScrollEnd(self.cfg.type == 'y'?self.target.scrollTop():self.target.scrollLeft()); //event
        }
    },
    _startScrollUp:function(e){
        var self = e.data.self;
        self.scrolling = true;
        self._scroll(-10);
    },
    _startScrollDown:function(e){
        var self = e.data.self;
        self.scrolling = true;
        self._scroll(10);
    },
    _startDrag:function(e){
        //e.preventDefault(); //enable the dragging outside of window/iframe in IE/Chrome
        var self = e.data.self;
        var pos = self.bar.position()
        self.dragPos = {x:parseInt(e.clientX-pos.left), y:parseInt(e.clientY-pos.top)};
        self.scrolling = true;
        
        var target = e.target;
        $(document).bind('mousemove.Scrollbar',function(ev){
            ev.preventDefault();
            if (self.cfg.type == 'y') {
                self.scrollTo((ev.clientY - self.dragPos.y - self.cfg.aW) * self.scrollLength / (self.len - 2 * self.cfg.aW));
            }else{
                self.scrollTo((ev.clientX - self.dragPos.x - self.cfg.aW) * self.scrollLength / (self.len - 2 * self.cfg.aW));
            }
        });
        $(document).bind('mouseup.Scrollbar',function(){

            
            
            self._stopDrag(e);
        });
        
        //disable text selection in IE
        if (target.setCapture) {
            document.body.unselectable = "on";
            document.body.onselectstart = function(){
                return false
            };
            target.setCapture();
        }
		document.body.onselectstart=function(){
			return false;
		}
        //disable text selection in FF/Chrome
        target.style.userSelect = target.style.MozUserSelect = "none";
    },
    _stopDrag:function(e){
        var self = e.data.self;
        $(document).unbind('mousemove.Scrollbar').unbind('mouseup.Scrollbar');
        self.CB.onScrollEnd(self.cfg.type == 'y'?self.target.scrollTop():self.target.scrollLeft()); //event
        
        //enable text selection in IE
        var target = e.target;
        if (target.releaseCapture) {
            
            document.body.unselectable = '';
            document.body.onselectstart = null;
            target.releaseCapture();
        }
		document.body.onselectstart=function(){
			return true;
		}
        //enable text selection in FF/Chrome
        target.style.userSelect = target.style.MozUserSelect = '';
    },
    _scroll:function(step){
        var self = this;
        if (this.scrolling) {
            this.scrollTimer = setTimeout(function(){
                self.scrollTo(self._getScrollTop() + step);
                self._scroll(step);
            }, 30);
        }else{
            clearTimeout(this.scrollTimer);
            this.scrollTimer = 0;
        }
    },
    _stopScroll:function(e){
        var self = e.data.self;
        self.scrolling = false;
        self.CB.onScrollEnd(self.cfg.type == 'y'?self.target.scrollTop():self.target.scrollLeft()); //event
    },
	clear:function(){
		this.mod.unbind(), this.bar.unbind(), this.btnUp.unbind(), this.btnDown.unbind();
		this.bar = this.btnUp = this.btnDown = null;
		this.mod.remove(), this.mod = null;
		for(var p in this){
            if(!p || p == 'clear'){continue;}
            this[p] = null;
            delete this[p];
        }
	}
}
/*ScrollPanel*/
Util.ScrollPanel = function(targetDOM, oConfig, callback){
    this.el;
    this.target = $(targetDOM);
    this.scrollbarX = {scrollTo:function(){}, reSize:function(){}};
    this.scrollbarY = {scrollTo:function(){}, reSize:function(){}};
    this.cfg = {
        disable:false,
        arrowSize:14,
        barWidth:12,
        showX:true,
        showY:true,
        delayRun:true
    };
    if(oConfig) {
        $.extend(this.cfg, oConfig);
    }
    this.CB = {
        onScroll:function(sLeft, sTop){},
        onScrollEnd:function(sLeft, sTop){}
    };
    if(callback) {
        $.extend(this.CB, callback);
    }
    this.scrollLeft = 0;
    this.scrollTop = 0;
    this.init();
};
Util.ScrollPanel.prototype = {
    init: function(){
        var self = this;
        this.el = $('<div class="rtq-scrollpanel">').css({
            //padding: '0 ' + this.cfg.arrowSize + 'px ' + this.cfg.arrowSize + 'px 0'
        }).mousewheel(function(e, d){
            if (self.scrollbarY.isShow) {
                e.preventDefault();
            }
            if (d > 0) {
                self.scrollbarY.scrollTo(self._getScrollTop() - 30);
            }
            else {
                self.scrollbarY.scrollTo(self._getScrollTop() + 30);
            }
            if (self.cfg.showY) {
                self.scrollTop = self.scrollbarY.target.scrollTop();
                self._onScrollEnd();
            }
            
        });
        this.target.css({
            overflow: 'hidden'
        });
        
        if (this.cfg.showX) {
            this.scrollbarX = new Util.Scrollbar(this, this.target, {
                type: 'x',
                aW: this.cfg.arrowSize
            }, {
                onScroll: function(s){
                    self.scrollLeft = s;
                    self._onScroll();
                },
                onScrollEnd: function(s){
                    self.scrollLeft = s;
                    self._onScrollEnd();
                }
            });
            this.scrollLeft = this.scrollbarX.target.scrollLeft();
        }
        if (this.cfg.showY) {
            this.scrollbarY = new Util.Scrollbar(this, this.target, {
                type: 'y',
                aW: this.cfg.arrowSize
            }, {
                onScroll: function(s){
                    self.scrollTop = s;
                    self._onScroll();
                },
                onScrollEnd: function(s){
                    self.scrollTop = s;
                    self._onScrollEnd();
                }
            });
            this.scrollTop = this.scrollbarY.target.scrollTop();
        }
        
        var oldParent = this.target.parent();
        this.target.appendTo(this.el);
        this.el.appendTo(oldParent);
        
        //this.reSize();
    },
    _checkNeedShowXY: function(w, h){
        var tgW = w||this.target.width();
        var tgH = h||this.target.height();
    

        if (tgW <= 0 && tgH <= 0) {
            return 0;
        }
        this.target[0].style.width = (tgW - this.cfg.arrowSize)>0?tgW - this.cfg.arrowSize + 'px':0 + 'px';
        this.target[0].style.height = (tgH - this.cfg.arrowSize)>0?tgH - this.cfg.arrowSize + 'px':0 + 'px';
        var tgSW = this.target[0].scrollWidth;
        var tgSH = this.target[0].scrollHeight;
        this.target[0].style.width = tgW > 0 ? tgW + this.cfg.arrowSize + 'px' : tgW;
        this.target[0].style.height = tgH + this.cfg.arrowSize + 'px';
        
        if (tgW >= tgSW && tgH >= tgSH) {
            return 0;
        }
        else 
            if (tgW < tgSW) {
                if (tgH - (this.scrollbarX.isShow ? 0 : this.cfg.arrowSize) < tgSH) {
                    return 3; //show XY
                }
                else {
                    return 1; //show X
                }
            }
            else 
                if (tgH - (this.scrollbarY.isShow ? 0 : this.cfg.arrowSize) < tgSH) {
                    if (tgW < tgSW) {
                        return 3; //show XY
                    }
                    else {
                        return 2; //show Y
                    }
                }
    },
    _onScroll:function(){
        this.CB.onScroll(this.scrollLeft, this.scrollTop);
    },
    _onScrollEnd:function(){
        this.CB.onScrollEnd(this.scrollLeft, this.scrollTop);
    },
    _resize:function(w, h){
        var parent = this.el.parent();
        w = w || parent.width();
        h = h || parent.height();
        var show = this._checkNeedShowXY(w, h);
        var offsetW = this.cfg.showY && (show == 3 || show == 2) ? this.cfg.barWidth : 0;
        var offsetH = this.cfg.showX && (show == 3 || show == 1) ? this.cfg.barWidth : 0;
        this.el.css({
            width: w,
            height: h
        });
        this.target.css({
            width: (w > offsetW) ? w - offsetW : 0,
            height: (h > offsetH) ? h - offsetH : 0
        });
        
        if(!this.cfg.showX){
            this.target[0].style.width = 'auto';
            if (offsetW >= 0) {
                this.target[0].style.marginRight = offsetW + 'px';//updated by wind @ 20120531, for fix QS-624
            } 
            this.el[0].style.width = 'auto';
        }
        if(!this.cfg.showY){
            this.target[0].style.height = 'auto';
            if (offsetH >= 0) {
                this.target[0].style.marginBottom = offsetH + 'px';//updated by wind @ 20120531, for fix QS-624
            } 
            this.el[0].style.height = 'auto';
        }
        
        this.scrollbarX.reSize(this.cfg.showX && (show == 3 || show == 1));
        this.scrollbarY.reSize(this.cfg.showY && (show == 3 || show == 2));

        if(this.scrollbarY.isShow && this.scrollbarX.isShow){
            this.el.addClass('rtq-scrollpanel-both');
        }else{
            this.el.removeClass('rtq-scrollpanel-both');
        }
    },
    reSize:function(w, h, afterResizeCallback){
        var self = this;
        if (this.cfg.delayRun == true) {
            Util.DelayRun('resize', function(){
                self._resize(w, h);
                if (afterResizeCallback) {
                    afterResizeCallback();
                }
            }, 10, this);
        }
        else {
            self._resize(w, h);
            if (afterResizeCallback) {
                afterResizeCallback();
            }
        }
    },
    reSizeRealTime:function(w, h){
        this._resize(w, h);
    },
    _getScrollTop:function(){
        return this.target.scrollTop();
    },
    setDelayRun:function(flag){
        this.cfg.delayRun = flag;
    },
	clear:function(){
		if(this.scrollbarX!=null && typeof(this.scrollbarX.clear)=="function"){
			this.scrollbarX.clear();
		}
		if(this.scrollbarY!=null && typeof(this.scrollbarY.clear)=="function"){
			this.scrollbarY.clear();
		}
		this.el.unbind();
		this.el.remove();
	}
};